<?php
declare(strict_types=1);

namespace Zms\Unit;

use StdClass;

class Type
{
    /**
     * @describe
     * @user zlf <zms-pro@qq.com> 2025/9/9
     * @param $var
     * @return stdClass {
     *       string $type 具体类型，可选值: 'string','json', 'float', 'int', 'bool', 'null', 'list', 'map', 'object', 'function', 'class', 'unknown'
     *       string $base 基础类型，可选值: 'string', 'number', 'bool', 'null', 'array', 'object', 'unknown'
     *  }
     */
    public static function get($var): StdClass
    {
        $type = gettype($var);
        if ($type === 'string') {
            if (Is::json($var)) {
                return Obj::create(['type' => 'json', 'base' => 'string']);
            }
            return Obj::create(['type' => 'string', 'base' => 'string']);
        } elseif ($type === 'double') {
            return Obj::create(['type' => 'float', 'base' => 'number']);
        } elseif ($type === 'integer') {
            return Obj::create(['type' => 'int', 'base' => 'number']);
        } elseif ($type === 'boolean') {
            return Obj::create(['type' => 'bool', 'base' => 'bool']);
        } elseif ($type === 'NULL') {
            return Obj::create(['type' => 'null', 'base' => 'null']);
        } elseif ($type === 'array') {
            return self::parseArray($var);
        } elseif ($type === 'object') {
            return self::parseObject($var);
        }
        return Obj::create(['type' => 'unknown', 'base' => 'unknown']);
    }

    private static function parseArray($var): StdClass
    {
        if (Is::list($var)) {
            return Obj::create(['type' => 'list', 'base' => 'array']);
        }
        return Obj::create(['type' => 'map', 'base' => 'array']);
    }

    private static function parseObject($var): StdClass
    {
        $class = get_class($var);
        if ($class === 'stdClass') {
            return Obj::create(['type' => 'object', 'base' => 'object']);
        } else if (is_callable($var)) {
            return Obj::create(['type' => 'function', 'base' => 'object']);
        }
        return Obj::create(['type' => 'class', 'base' => 'object']);
    }


    /**
     * @describe 数据类型
     * @user zlf <zms-pro@qq.com> 2025/9/9
     * @param $var
     * @return 'string' | 'json' | 'float' | 'int' | 'bool' | 'null' | 'list' | 'map' | 'object' | 'function' | 'class' | 'unknown'
     */
    public static function typeof($var)
    {
        return self::get($var)->type;
    }

    /**
     * @describe
     * @user zlf <zms-pro@qq.com> 2025/9/9
     * @param $var
     * @return  'string' | 'number' | 'bool' | 'null' | 'array' | 'object' | 'unknown'
     */
    public static function base($var): string
    {
        return self::get($var)->base;
    }
}